/*
 * main.cpp
 *
 *  Created on: 2013-1-15
 *      Author: heqiu
 */

#include "myall.h"

ScreenUnit g_ScreenUnit;
ConfUnit g_ConfUnit;
SDL_Event g_event;
MapUnit g_MapUnit;
map<uint32_t, string> g_mapBuildingType;
map<uint32_t, string> g_mapAnimalType;
vector<BuildingUnit> g_vctBuilding;
//vector<AnimalUnit> g_vctAnimal;
map<uint32_t, AnimalUnit> g_mapAnimal;
AnimalPosition g_AnimalPosition;
TTF_Font *g_font = NULL;
SDL_Color g_textColor = { 0, 0, 0 };
AnimalMoving g_AnimalMoving;

const float DOT_L = 0.8;
const float DOT_S = 0.2;

void drawWindow();
class ShowThread: public ThreadUnit {
public:
	void run() {
		while (true) {
			//printf("hello...\n");
			drawWindow();
			g_ScreenUnit.show();
			SDL_Delay(100);
		}
	}
};
class MovingThread: public ThreadUnit {
public:
	void run() {
		while (true) {
			g_AnimalMoving.moving();
			SDL_Delay(100);
		}
	}
};

ShowThread g_ShowThread;
MovingThread g_MovingThread;

void drawPoint(int32_t iX, int32_t iY) {
	MyPoint p(iX, iY);

	if (!g_MapUnit.bPointIn(p)) {
		return;
	}
	MyPoint pw;
	g_MapUnit.getWinPoint(p, pw);

	uint32_t uiBuilding = g_MapUnit.getBuilding(iX, iY);
	{
		SDL_Rect wall;
		wall.x = ((pw.m_x) * 2 * (DOT_L + DOT_S) / 2) * g_ScreenUnit.m_uiWinSize
				- g_ScreenUnit.m_Pos.m_x;
		wall.y = ((pw.m_y) * (DOT_L + DOT_S) / 2) * g_ScreenUnit.m_uiWinSize
				- g_ScreenUnit.m_Pos.m_y;
		wall.w = (DOT_L * 2) * g_ScreenUnit.m_uiWinSize;
		wall.h = (DOT_L) * g_ScreenUnit.m_uiWinSize;

		SDL_FillRect(g_ScreenUnit.m_pScreen, &wall,
				SDL_MapRGB(g_ScreenUnit.m_pScreen->format, 0x00, 0xff, 0xff));

		if (uiBuilding > 0) {
			if (BuildingUnit::isWay(uiBuilding)) {
				SDL_FillRect(g_ScreenUnit.m_pScreen, &wall,
						SDL_MapRGB(g_ScreenUnit.m_pScreen->format, 0xff, 0x00,
								0x00));
			} else {
				SDL_FillRect(g_ScreenUnit.m_pScreen, &wall,
						SDL_MapRGB(g_ScreenUnit.m_pScreen->format, 0x00, 0x00,
								0xff));
			}
		}

		char buf[64];
		sprintf(buf, "(%d-%d)", pw.m_x, pw.m_y);
		//sprintf(buf, "(%d,%d)", iX, iY);
		SDL_Surface *message = TTF_RenderText_Solid(g_font, buf, g_textColor);
		SDL_BlitSurface(message, NULL, g_ScreenUnit.m_pScreen, &wall);
		SDL_FreeSurface(message);

		vector<uint32_t> vctAnimal;
		g_AnimalPosition.getAnimal(iX, iY, vctAnimal);
		//printf("size=%d\n", vctAnimal.size());
		if (vctAnimal.size() > 0) {
			for (uint32_t ui = 0; ui < vctAnimal.size(); ui++) {
				uint32_t uiId = vctAnimal.at(ui);
				map<uint32_t, AnimalUnit>::iterator it = g_mapAnimal.find(uiId);
				if (it != g_mapAnimal.end()) {
					MyFPoint fp;
					fp.m_x = it->second.m_fXshift + iX;
					fp.m_y = it->second.m_fYshift + iY;
					MyFPoint fpw;
					g_MapUnit.getWinPoint(fp, fpw);
					SDL_Rect offset;
					offset.x = (((fpw.m_x) * 2) * (DOT_L + DOT_S) / 2)
							* g_ScreenUnit.m_uiWinSize - 200
							- g_ScreenUnit.m_Pos.m_x;
					offset.y = ((fpw.m_y) * (DOT_L + DOT_S) / 2)
							* g_ScreenUnit.m_uiWinSize - 200
							- g_ScreenUnit.m_Pos.m_y;
					SDL_BlitSurface(it->second.m_pSDL_Surface, NULL,
							g_ScreenUnit.m_pScreen, &offset);
				}
			}
		}
	}

}
void drawWindow() {
	g_ScreenUnit.white();

	{
		//g_MapUnit.cycle(drawPoint);
		int32_t iX = g_ScreenUnit.getWinPosX();
		int32_t iY = g_ScreenUnit.getWinPosY();

		uint32_t uiW = g_ScreenUnit.getWinWidth();
		uint32_t uiH = g_ScreenUnit.getWinHeight();

		for (uint32_t uj = 0; uj < uiH; uj++) {
			for (uint32_t ui = 0; ui < uiW; ui++) {
				MyPoint pw;
				pw.m_x = iX + ui;
				pw.m_y = iY + uj;
				MyPoint pm;
				g_MapUnit.getMapPoint(pw, pm);
				drawPoint(pm.m_x, pm.m_y);
			}
		}
	}
	for (uint32_t ui = 0; ui < g_vctBuilding.size(); ui++) {
		MyPoint pw;
		g_MapUnit.getWinPoint(g_vctBuilding.at(ui).m_pPos, pw);

		SDL_Rect offset;
		offset.x = ((pw.m_x) * 2 * (DOT_L + DOT_S) / 2)
				* g_ScreenUnit.m_uiWinSize - 200 - g_ScreenUnit.m_Pos.m_x;
		offset.y = ((pw.m_y) * (DOT_L + DOT_S) / 2) * g_ScreenUnit.m_uiWinSize
				- 200 - g_ScreenUnit.m_Pos.m_y;
		SDL_BlitSurface(g_vctBuilding.at(ui).m_pSDL_Surface, NULL,
				g_ScreenUnit.m_pScreen, &offset);
	}
	//exit(0);
}

void handle_events() {
	if (g_event.type == SDL_MOUSEMOTION) {
		g_ScreenUnit.mouseMoving(g_event.motion.x, g_event.motion.y);
	} else if (g_event.type == SDL_MOUSEBUTTONDOWN) {
		g_ScreenUnit.mouseDown(g_event.motion.x, g_event.motion.y);
	} else if (g_event.type == SDL_MOUSEBUTTONUP) {
		g_ScreenUnit.mouseUp(g_event.motion.x, g_event.motion.y);
	}
	//drawWindow();
	//g_ScreenUnit.show();
}
int main(int argc, char ** argv) {
	int32_t iRet = g_ConfUnit.load("./conf/root.xml");
	if (iRet != 0) {
		myexit(__FILE__, __LINE__, iRet, "g_ConfUnit.load");
	}
	printf("width=%u\n", g_ConfUnit.getWindowWidth());
	printf("height=%u\n", g_ConfUnit.getWindowHeight());
	g_ScreenUnit.m_uiWinSize = g_ConfUnit.getWindowSize();
	g_ConfUnit.getBuildingType(g_mapBuildingType);
	g_ConfUnit.getAnimalType(g_mapAnimalType);
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
		myexit(__FILE__, __LINE__, -1, "SDL_Init");
	}

	TTF_Init();
	g_font = TTF_OpenFont("lazy.ttf", 10);
	if (g_font == NULL) {
		myexit(__FILE__, __LINE__, -1, "TTF_OpenFont");
	}
	iRet = g_ScreenUnit.init(g_ConfUnit.getWindowWidth(),
			g_ConfUnit.getWindowHeight(), g_ConfUnit.getWindowBPP(),
			g_ConfUnit.getWindowCaption().c_str());
	g_ScreenUnit.m_Pos.m_x = g_ConfUnit.getWindowX();
	g_ScreenUnit.m_Pos.m_y = g_ConfUnit.getWindowY();
	if (iRet != 0) {
		myexit(__FILE__, __LINE__, iRet, "g_ScreenUnit.init");
	}

	ScaleUnit stScaleUnit;
	iRet = stScaleUnit.init(g_ConfUnit.getMapLong());
	if (iRet != 0) {
		myexit(__FILE__, __LINE__, iRet, "stScaleUnit.init");
	}
	iRet = g_MapUnit.init(&stScaleUnit, g_ConfUnit.getMapShort(),
			g_ConfUnit.getMapLong());
	if (iRet != 0) {
		myexit(__FILE__, __LINE__, iRet, "stMapUnit.init");
	}
	g_AnimalPosition.init(g_ConfUnit.getMapLong());
	g_AnimalMoving.init(&g_AnimalPosition);
	//建筑
	{
		g_ConfUnit.getBuildings(g_vctBuilding);
		for (uint32_t ui = 0; ui < g_vctBuilding.size(); ui++) {
			g_MapUnit.setBuilding(g_vctBuilding.at(ui));
			string sName = "./image/"
					+ g_mapBuildingType[g_vctBuilding.at(ui).m_iType] + ".bmp";
			g_vctBuilding.at(ui).loadImage(sName);
		}
	}
	//动物
	{
		g_ConfUnit.getAnimals(g_mapAnimal);
		for (map<uint32_t, AnimalUnit>::iterator it = g_mapAnimal.begin();
				it != g_mapAnimal.end(); it++) {
			g_AnimalPosition.addAnimal(it->first, it->second.m_pPos.m_x,
					it->second.m_pPos.m_y);
			string sName = "./image/" + g_mapAnimalType[it->second.m_iType]
					+ ".bmp";
			it->second.loadImage(sName);
			it->second.m_uiSpeed = 1000;
		}
	}

	//道路
	{
		map<uint32_t, set<pair<uint32_t, uint32_t> > > mapWay;
		g_ConfUnit.getWays(mapWay);
		map<uint32_t, set<pair<uint32_t, uint32_t> > >::iterator it;
		for (it = mapWay.begin(); it != mapWay.end(); it++) {
			set<pair<uint32_t, uint32_t> > & stSet = it->second;
			set<pair<uint32_t, uint32_t> >::iterator it2;
			for (it2 = stSet.begin(); it2 != stSet.end(); it2++) {
				g_MapUnit.setWay(it2->first, it2->second, (WayType) it->first);
			}
		}
	}

	//设置行走动物
	{
		AnimalUnit & stOne = g_mapAnimal[1];
		g_AnimalMoving.addAnimal(stOne);
		SearchUnit::findWay(24, 40, 25, 30, g_MapUnit, stOne.m_vctPath);
		printf("stOne.m_vctPath.size=%d\n", stOne.m_vctPath.size());
	}

	g_ShowThread.start();
	g_MovingThread.start();

	bool quit = false;
	while (quit == false) {
		while (SDL_PollEvent(&g_event)) {
			if (g_event.type == SDL_QUIT) {
				quit = true;
			}
			handle_events();
		}
		SDL_Delay(100);
	}
	SDL_Quit();
	return 0;
}

